#ifndef TB_BASE_GLOBAL_INITIALIZER_HPP__
#define TB_BASE_GLOBAL_INITIALIZER_HPP__

#include "make_containers.hpp"
#include "initializer.hpp"

TB_NAMESPACE_BEGIN

namespace detail {

struct TB_BASE_API GlobalInitializerRegister {
	GlobalInitializerRegister(
		const std::string& name,
		const InitializerContext::InitializerFunction& func,
		const std::vector<std::string>& prerequisites,
		const std::vector<std::string>& depends);
};

}

struct TB_BASE_API GlobalInitializer {
	static Result Execute(const InitializerContext& context);
};

TB_NAMESPACE_END

#define TB_NO_PREREQUISITES (NULL)

#define TB_NO_DEPENDS (NULL)

#define TB_DEFAULT_PREREQUISITES ("default")

#define TB_DEFAULT_DEPENDS ("default")

#define TB_INITIALIZER(NAME) \
	TB_INITIALIZER_WITH_PREREQUISTES(NAME, TB_NO_PREREQUISTES)

#define TB_INITIALIZER_WITH_PREREQUISTES(NAME, PREREQUISITES) \
	TB_INITIALIZER_GENERAL(NAME, PREREQUISTES, TB_NO_DEPENDS)

#define TB_INITIALIZER_GENERAL(NAME, PREREQUISITES, DEPENDS) \
	TB_NAMESPACE::Result __TB_INITIALIZER_FUNCTION_NAME(NAME)(const TB_NAMESPACE::InitializerContext&); \
	namespace { \
		TB_NAMESPACE::detail::GlobalInitializerRegister _TBGlobalInitializerRegister_##NAME( \
			#NAME, \
			__TB_INITIALIZER_FUNCTION_NAME(NAME), \
			TB_MAKE_STRING_VECTOR PREREQUISITES, \
			TB_MAKE_STRING_VECTOR DEPENDS \
		); \
	} \
	TB_NAMESPACE::Result __TB_INITIALIZER_FUNCTION_NAME(NAME)

#define __TB_INITIALIZER_FUNCTION_NAME(NAME) _TBInitializerFunction_##NAME

#endif // TB_BASE_GLOBAL_INITIALIZER_HPP__
